<template>
  <div v-for="item in list" :key="item.id">
    <div class="title">
      <el-checkbox @change="checkAllChange(item)" v-model="item.checkAll" :indeterminate="item.indeterminate">{{
          item.name
      }}</el-checkbox>
    </div>
    <div class="group">
      <!-- checkbox-group 需要一个v-model的数组，里面是下面每个checkbox 的label -->
      <el-checkbox-group @change="groupChange(item)" v-model="item.checkedIds">
        <div class="item" v-for="child in item.children" :key="child.id">
          <el-checkbox :label="child.id">{{ child.name }}</el-checkbox>
        </div>
      </el-checkbox-group>
    </div>
  </div>
  <div class="save">
    <el-button type="primary" @click="save">保存</el-button>
    <!-- 清空只需要把 数组里面的每个  checkedIs 清空，控制一个 checkAll 和半选 -->
    <el-button>清空</el-button>
  </div>
</template>

<script setup lang="ts">
import { user } from "@/api";
import { ElMessage, ElMessageBox } from "element-plus";
import { reactive, ref, toRefs } from "vue";
import { useRoute } from "vue-router";
const route = useRoute();

const checkAllChange = (item: ICategory) => {
  // 判断当前是否是全选，如果是 让下面的每个都是true，否则就是false
  item.checkedIds = item.checkAll ? item.children.map((child) => child.id) : [];
  item.indeterminate = !item.checkAll && item.checkedIds.length !== 0;
};

const groupChange = (item: ICategory) => {
  // 判断是全选还是半选还是全不选
  item.checkAll = item.checkedIds.length === item.children.length;
  item.indeterminate = !item.checkAll && item.checkedIds.length !== 0;
};

/**
 *  当前页面的目标：
 *    1. 把从后端请求回来的数据(当前点击的角色拥有的资源)，进行勾选
 *      1.1 发三个请求，a.得到所有分类 b.得到所有的资源 c.得到当前角色已经有的资源
 *    2. 修改过后，需要向服务器发请求保存
 */

type ICategory = IResourceCategoryModel & {
  children: IResourceModel[];
  checkedIds: number[];
  checkAll: boolean;
  indeterminate: boolean;
};

interface IState {
  list: ICategory[];
}

// 准备数据
const state = reactive<IState>({
  list: [],
});

if (route.query.id) {
  // 保证两三个请求都要成功
  Promise.all([
    user.getAllResourceCategoryApi(),
    user.getAllResourceApi(),
    user.getListRoleResourceApi(parseInt(route.query.id as string)),
  ]).then(([res1, res2, res3]) => {
    // 请求成功了
    if (res1.code === 200 && res2.code === 200 && res3.code === 200) {
      // 分类
      // res1.data
      // res1.data 里面的 子级
      // res2.data
      state.list = res1.data.map((item) => ({
        ...item,
        children: [], // 该分类下的所有的资源
        checkedIds: [], // 该分类下勾选id
        checkAll: false,
        indeterminate: false,
      }));
      res2.data.forEach((child) => {
        const p = state.list.find((p) => p.id === child.categoryId);
        p?.children.push(child);
      });
      // 要根据 res3 得到的 当前角色拥有的 资源，让 list[i].checkedIds 里面存着的是 res3.data 的id
      // list[i] == { id: number,  checkedIds : []}
      // res3.data == [ {id:number,categoryId : number} ]
      // 需要把 res3.data[j].id 放到  list[i].checkedIds 里面
      // 让 checked-group 里面的 多选勾选上
      state.list.forEach((item) => {
        res3.data.forEach((child) => {
          if (child.categoryId === item.id) {
            item.checkedIds.push(child.id);
          }
        });
      });

      // 处理 list 里面的 数据的勾选状态
      state.list.forEach((item) => {
        // 什么状态下是全选？
        item.checkAll = item.checkedIds.length === item.children.length;
        // 什么状态下，是半选？
        item.indeterminate = !item.checkAll && item.checkedIds.length !== 0;
      });
    }
  });
}
const save = () => {
  ElMessageBox.confirm("确定要保存嘛")
    .then(() => {
      // 发请求
      user
        .allocResourceApi({
          roleId: parseInt(route.query.id as string),
          resourceIds: state.list
            .map((item) => item.checkedIds)
            .reduce((pre, cur) => {
              return pre.concat(cur);
            }, []),
        })
        .then((res) => {
          ElMessage({
            message: res.message,
            type: res.code === 200 ? "success" : "error",
          });
        });
    })
    .catch(() => { });
};

const { list } = toRefs(state);
</script>

<style lang="less" scoped>
.title {
  padding: 10px;
  background-color: #f2f6fc;
}

.group {
  padding: 10px;

  .item {
    width: 33%;
  }
}

.save {
  display: flex;
  justify-content: center;
}

:deep(.el-checkbox-group) {
  display: flex;
  flex-wrap: wrap;
}
</style>
